#include "stdafx.h"

#include "Core.h"
#include "Gui.h"
#include "Lua-Main.h"
#include "Logging.h"

using namespace std;

bool Core::CheckForSection(const String& aCall, const String& aSection)
{
    bool Result = false;

    mEngine.Call(aCall, "s>b", aSection.c_str(), &Result);

    return Result;
}

void Core::MoveToNextShowableSection()
{
    auto Start = find (mSections.cbegin(), mSections.cend(), CurrentSection());
    MoveToShowableSection(Start, mSections.cend());
}

void Core::MoveToPreviousShowableSection()
{
    auto Start = find (mSections.crbegin(), mSections.crend(), CurrentSection());
    MoveToShowableSection(Start, mSections.crend());
}

bool Core::NextCommand()
{
    bool Result = CheckForSection("NextCommand", CurrentSection());

    if (Result) {
        MoveToNextShowableSection();
    }

    return Result;
}

bool Core::BackCommand()
{
    bool Result = CheckForSection("BackCommand", CurrentSection());

    if (Result) {
        MoveToPreviousShowableSection();
    }

    return Result;
}

bool Core::ShouldSkipSection(const String& aSection)
{
    return CheckForSection("ShouldSkipSection", aSection);
}

void Core::Connect(Ui& aGui)
{
    mSections = aGui.Sections();

    if (mSections.empty()) {
        throw out_of_range("No sections passed to core");
    }

    mGui = &aGui;
}

void Core::ShowSectionEvent(const String& aSection)
{
    mGui->MoveToSection(aSection);
}

void Core::Initialize(const std::list<String>& aFiles)
{
    mEngine.Initialize(aFiles);
}

int Core::RunScript()
{
    mEngine.RegisterCore(*this);
    bool Continue = false;
    int Result = 0;

    mEngine.Call("InitializeScript", ">b", &Continue);

    if (Continue) {
        mEngine.Call("StartScript", ">i", Result);
    }

    return Result;
}

void Core::Log(const String& aMessage)
{
    Logging::Logger().Write(aMessage);
}

void Core::StartUi()
{
    mGui->Start();
}

void Core::InitializeSection(const String& aSection)
{
    mEngine.Call("InitializeSection", "s", aSection.c_str());
}

void Core::SetLabelText(const String& aSection, const String& aLabel, const String& aText)
{
    mGui->SetLabelText(aSection, aLabel, aText);
}

String Core::CurrentSection()
{
    return mGui->CurrentSection();
}
